package net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators;

import net.lucode.hackware.magicindicator.FragmentContainerHelper;
import net.lucode.hackware.magicindicator.buildins.UIUtil;
import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
import net.lucode.hackware.magicindicator.buildins.commonnavigator.model.PositionData;
import ohos.agp.animation.Animator;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.util.List;

/**
 * 带有小尖角的直线指示器
 *
 * @since 2020-09-29
 */
public class TriangularPagerIndicator extends Component implements IPagerIndicator, Component.DrawTask {
    private List<PositionData> mPositionDataList;
    private Paint mPaint;
    private int mLineHeight;
    private int mLineColor;
    private int mTriangleHeight;
    private int mTriangleWidth;
    private boolean mIsReverse;
    private float mYOffset;

    private Path mPath = new Path();
    private int mStartInterpolator = Animator.CurveType.LINEAR;
    private float mAnchorX;

    /**
     * TriangularPagerIndicator
     *
     * @param context context
     */
    public TriangularPagerIndicator(Context context) {
        super(context);
        init(context);
    }

    private void init(Context context) {
        mPaint = new Paint();
        mPaint.setSubpixelAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL_STYLE);
        mLineHeight = UIUtil.vp2px(context, 3);
        mTriangleWidth = UIUtil.vp2px(context, 14);
        mTriangleHeight = UIUtil.vp2px(context, 8);
        addDrawTask(this);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        mPaint.setColor(new Color(mLineColor));
        if (mIsReverse) {
            canvas.drawRect(0, getHeight() - mYOffset - mTriangleHeight, getWidth(),
                    getHeight() - mYOffset - mTriangleHeight + mLineHeight, mPaint);
        } else {
            canvas.drawRect(0, getHeight() - mLineHeight - mYOffset, getWidth(),
                    getHeight() - mYOffset, mPaint);
        }
        mPath.reset();
        if (mIsReverse) {
            mPath.moveTo(mAnchorX - (float) mTriangleWidth / 2,
                    (float) getHeight() - mYOffset - (float) mTriangleHeight);
            mPath.lineTo(mAnchorX, (float) getHeight() - mYOffset);
            mPath.lineTo(mAnchorX + (float) mTriangleWidth / 2,
                    (float) getHeight() - mYOffset - (float) mTriangleHeight);
        } else {
            mPath.moveTo(mAnchorX - (float) mTriangleWidth / 2, (float) getHeight() - mYOffset);
            mPath.lineTo(mAnchorX, (float) getHeight() - (float) mTriangleHeight - mYOffset);
            mPath.lineTo(mAnchorX + (float) mTriangleWidth / 2, (float) getHeight() - mYOffset);
        }
        mPath.close();
        canvas.drawPath(mPath, mPaint);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (mPositionDataList == null || mPositionDataList.isEmpty()) {
            return;
        }
        int nextPosition = position + 1;
        if (positionOffsetPixels < 0) {
            nextPosition = position - 1;
        }

        // 计算锚点位置
        PositionData current = FragmentContainerHelper.getImitativePositionData(mPositionDataList, position);
        PositionData next = FragmentContainerHelper.getImitativePositionData(mPositionDataList, nextPosition);

        float leftX = current.mLeft + (current.mRight - current.mLeft) / 2;
        float rightX = next.mLeft + (next.mRight - next.mLeft) / 2;

        mAnchorX = leftX + (rightX - leftX) * positionOffset;
        invalidate();
    }

    @Override
    public void onPageSelected(int position) {
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    @Override
    public void onPositionDataProvide(List<PositionData> dataList) {
        mPositionDataList = dataList;
    }

    /**
     * getLineHeight
     *
     * @return mLineHeight
     */
    public int getLineHeight() {
        return mLineHeight;
    }

    /**
     * setLineHeight
     *
     * @param lineHeight lineHeight
     */
    public void setLineHeight(int lineHeight) {
        mLineHeight = lineHeight;
    }

    /**
     * getLineColor
     *
     * @return mLineColor
     */
    public int getLineColor() {
        return mLineColor;
    }

    /**
     * setLineColor
     *
     * @param lineColor lineColor
     */
    public void setLineColor(int lineColor) {
        mLineColor = lineColor;
    }

    /**
     * getTriangleHeight
     *
     * @return mTriangleHeight
     */
    public int getTriangleHeight() {
        return mTriangleHeight;
    }

    /**
     * setTriangleHeight
     *
     * @param triangleHeight triangleHeight
     */
    public void setTriangleHeight(int triangleHeight) {
        mTriangleHeight = triangleHeight;
    }

    /**
     * getTriangleWidth
     *
     * @return mTriangleWidth
     */
    public int getTriangleWidth() {
        return mTriangleWidth;
    }

    /**
     * setTriangleWidth
     *
     * @param triangleWidth triangleWidth
     */
    public void setTriangleWidth(int triangleWidth) {
        mTriangleWidth = triangleWidth;
    }

    /**
     * getStartInterpolator
     *
     * @return mStartInterpolator
     */
    public int getStartInterpolator() {
        return mStartInterpolator;
    }

    /**
     * setStartInterpolator
     *
     * @param startInterpolator startInterpolator
     */
    public void setStartInterpolator(int startInterpolator) {
        mStartInterpolator = startInterpolator;
    }

    /**
     * isReverse
     *
     * @return mIsReverse
     */
    public boolean isReverse() {
        return mIsReverse;
    }

    /**
     * setReverse
     *
     * @param isReverse isReverse
     */
    public void setReverse(boolean isReverse) {
        mIsReverse = isReverse;
    }

    /**
     * getYOffset
     *
     * @return mYOffset
     */
    public float getYOffset() {
        return mYOffset;
    }

    /**
     * setYOffset
     *
     * @param yOffset yOffset
     */
    public void setYOffset(float yOffset) {
        mYOffset = yOffset;
    }
}